/**
 * 
 */
package net.sf.rose.common;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Date;

import net.sf.rose.util.DateFormat;

/**
 * @author fengjian
 * 
 */
public class BeanStore {

	/**
	 * 
	 */
	private Object bean = null;

	/**
	 * 
	 */
	private Class<?> c = null;

	/**
	 * 
	 */
	private DateFormat dateBean = null;

	/**
	 * 
	 */
	public BeanStore() {
		dateBean = new DateFormat();
	}

	/**
	 * 
	 */
	public BeanStore(Object bean) {
		this();
		setBean(bean);
	}

	/**
	 * 
	 */
	public void setDatePattern(String datePattern) {
		dateBean.setDatePattern(datePattern);
	}

	/**
	 * @return the bean
	 */
	public Object getBean() {
		return bean;
	}

	/**
	 * 
	 */
	public void setBean(Object bean) {
		this.bean = bean;
	}

	/**
	 * 
	 */
	public void setProperty(String key, Object val) {
		c = bean.getClass();
		Field field = getField(c, key);
		if (field != null) {
			setValue(field, key, val);
		}
	}

	/**
	 * 
	 */
	private Field getField(Class<?> b, String key) {
		Field[] fields = b.getDeclaredFields();
		for (Field f : fields) {
			if (f.getName().equals(key)) {
				return f;
			}
		}
		c = b.getSuperclass();
		if (!c.equals(Object.class)) {
			return getField(c, key);
		}
		return null;
	}

	/**
	 * 
	 */
	private void setValue(Field f, String key, Object val) {
		try {
			Method m = c.getMethod("set" + firstLetterUpper(key), f.getType());
			if (m != null) {
				Object o = null;
				Class<?> c = f.getType();
				if (c.equals(String.class)) {
					o = val;
				} else if (c.equals(Long.class)) {
					if (val != null && !val.equals("")) {
						o = Long.parseLong(val.toString());
					}
				} else if (c.equals(Integer.class)) {
					if (val != null && !val.equals("")) {
						o = Integer.parseInt(val.toString());
					}
				} else if (c.equals(Timestamp.class)) {
					if (val != null && !val.equals("")) {
						o = dateBean.toTimestamp(val.toString());
					}
				} else if (c.equals(Date.class)) {
					if (val != null && !val.equals("")) {
						o = dateBean.format(val.toString());
					}
				} else if (c.equals(Double.class)) {
					if (val != null && !val.equals("")) {
						o = Double.parseDouble(val.toString());
					}
				} else if (c.equals(BigDecimal.class)) {
					if (val != null && !val.equals("")) {
						BigDecimal bd = new BigDecimal(val.toString());
						o = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
					}
				} else {
					o = val;
				}
				m.invoke(bean, o);
			}
		} catch (Exception e) {
			RunException re = new RunException(e);
			re.putMessage("error:" + key + ":" + val);
			throw re;
		}
	}

	/**
	 * 
	 */
	public Object getProperty(String key) {
		c = bean.getClass();
		Field field = getField(c, key);
		if (field != null) {
			return getValue(field, key);
		}
		return null;
	}

	/**
	 * 
	 */
	private Object getValue(Field f, String key) {
		try {
			Method m = c.getMethod("get" + firstLetterUpper(key));
			if (m != null) {
				return m.invoke(bean);
			}
		} catch (Exception e) {
			throw new RunException(e);
		}
		return null;
	}

	/**
	 * 
	 */
	public String getBeanString() {
		c = bean.getClass();
		StringBuffer buf = new StringBuffer();
		getBeanBufferString(c, buf);
		return buf.toString();
	}

	/**
	 * 
	 */
	private void getBeanBufferString(Class<?> c, StringBuffer buf) {
		String name = null;
		Object obj = null;
		Field[] fields = c.getDeclaredFields();
		for (Field f : fields) {
			name = f.getName();
			obj = this.getValue(f, name);
			if (obj != null) {
				buf.append(name + "=" + obj).append(",");
			}
		}
		c = c.getSuperclass();
		if (!c.equals(Object.class)) {
			getBeanBufferString(c, buf);
		}
	}

	/**
	 * 
	 */
	private String firstLetterUpper(String string) {
		return Character.toUpperCase(string.charAt(0)) + string.substring(1);
	}

}
